import { EventEnum } from '../base/JeesEnum';

interface FuncItem {
    cb: Function;
    ctx: unknown;
}

export class EventManager {

    private map: Map<EventEnum, Array<FuncItem>> = new Map();

    static init(_jees: any) {
        _jees.E = new EventManager();
    }

    /**
     * 监听
     * @param event 事件名称
     * @param cb 执行方法
     * 
     * Jees.E.on(EventEnum.GameStart, this.handleGameStart, this);
     */
    on(event: EventEnum, cb: Function, ctx: unknown) {
        if (this.map.has(event)) {
            this.map.get(event)?.push({ cb, ctx });
        } else {
            this.map.set(event, [{ cb, ctx }]);
        }
    }

    /**
     * 取消监听
     * @param event 事件名称
     * @param cb 执行方法
     */
    off(event: EventEnum, cb: Function, ctx: unknown) {
        if (this.map.has(event)) {
            const index = this.map.get(event)?.findIndex((i) => cb === i.cb && i.ctx === ctx) || -1;
            index > -1 && this.map.get(event)?.splice(index, 1);
        }
    }

    /**
     * 触发执行
     * @param event 事件名称
     * @param params 参数
     * 
     * Jees.E.emit(EventEnum.GameEnd, {key: value});
     */
    emit(event: EventEnum, ...params: unknown[]) {
        if (this.map.has(event)) {
            this.map.get(event)?.forEach(({ cb, ctx }) => {
                cb.apply(ctx, params);
            });
        }
    }

    clear() {
        this.map.clear();
    }

}